package com.huawei.demo;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.ddm.v1.DdmClient;
import com.huaweicloud.sdk.ddm.v1.model.CreateUsersDatabases;
import com.huaweicloud.sdk.ddm.v1.model.CreateUsersInfo;
import com.huaweicloud.sdk.ddm.v1.model.CreateUsersReq;
import com.huaweicloud.sdk.ddm.v1.model.CreateUsersRequest;
import com.huaweicloud.sdk.ddm.v1.model.CreateUsersResponse;
import com.huaweicloud.sdk.ddm.v1.model.ListUsersRequest;
import com.huaweicloud.sdk.ddm.v1.model.ListUsersResponse;
import com.huaweicloud.sdk.ddm.v1.region.DdmRegion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

public class CreateUserDemo {

    private static final Logger LOGGER = LoggerFactory.getLogger(CreateUserDemo.class.getName());

    /**
     * args[0] = <<YOUR AK>>
     * args[1] = <<YOUR SK>>
     * args[2] = <<YOUR INSTANCE_ID>>
     * args[3] = <<YOUR REGION_ID>>
     * args[4] = <<待关联的数据库名>>
     * args[5] = <<用户名>>
     * args[6] = <<密码>>
     **/
    public static void main(String[] args) {
        if (args.length != 7) {
            LOGGER.error("The expected number of parameters is 7");
            return;
        }

        String ak = args[0];
        String sk = args[1];
        String instanceId = args[2];
        String regionId = args[3];

        ICredential auth = new BasicCredentials()
                .withAk(ak)
                .withSk(sk);
        DdmClient client = DdmClient.newBuilder()
                .withCredential(auth)
                .withRegion(DdmRegion.valueOf(regionId))
                .build();

        // 查看用户列表
        listUsers(client, instanceId);

        // 创建具有全部权限的用户，并关联已创建逻辑库
        String dbName = args[4];
        String userName = args[5];
        String userPwd = args[6];

        createUser(client, instanceId, userName, userPwd, buildFullAuthorities(), dbName);

        // 查看用户列表
        listUsers(client, instanceId);
    }

    private static void listUsers(DdmClient client, String instanceId) {
        ListUsersRequest request = new ListUsersRequest();
        request.withInstanceId(instanceId);

        Consumer<ListUsersRequest> consumer = (req) -> {
            ListUsersResponse response = client.listUsers(req);
            LOGGER.info(response.toString());
        };

        executeRequest(consumer, request);
    }

    private static void createUser(DdmClient client, String instanceId, String userName, String userPwd,
        List<CreateUsersInfo.BaseAuthorityEnum> authorities, String dbName) {
        CreateUsersDatabases databases = new CreateUsersDatabases().withName(dbName);
        CreateUsersInfo usersInfo = new CreateUsersInfo()
                .withName(userName)
                .withPassword(userPwd)
                .withDatabases(Collections.singletonList(databases))
                .withBaseAuthority(authorities);

        CreateUsersReq uses = new CreateUsersReq().withUsers(Collections.singletonList(usersInfo));
        CreateUsersRequest request = new CreateUsersRequest()
                .withInstanceId(instanceId)
                .withBody(uses);

        Consumer<CreateUsersRequest> consumer = (req) -> {
            CreateUsersResponse response = client.createUsers(req);
            LOGGER.info(response.toString());
        };

        executeRequest(consumer, request);
    }

    private static List<CreateUsersInfo.BaseAuthorityEnum> buildFullAuthorities() {
        return Arrays.asList(
            CreateUsersInfo.BaseAuthorityEnum.CREATE,
            CreateUsersInfo.BaseAuthorityEnum.DROP,
            CreateUsersInfo.BaseAuthorityEnum.ALTER,
            CreateUsersInfo.BaseAuthorityEnum.INDEX,
            CreateUsersInfo.BaseAuthorityEnum.INSERT,
            CreateUsersInfo.BaseAuthorityEnum.DELETE,
            CreateUsersInfo.BaseAuthorityEnum.UPDATE,
            CreateUsersInfo.BaseAuthorityEnum.SELECT
        );
    }

    private static <T> void executeRequest(Consumer<T> consumer, T request) {
        try {
            consumer.accept(request);
        } catch (ConnectionException e) {
            LOGGER.error("ConnectionException", e);
        } catch (RequestTimeoutException e) {
            LOGGER.error("RequestTimeoutException ", e);
        } catch (ServiceResponseException e) {
            LOGGER.error("httpStatusCode: {}, errorCode: {}, errorMsg: {}",
                    e.getHttpStatusCode(), e.getErrorCode(), e.getErrorMsg());
        } catch (Exception e) {
            LOGGER.error("Unexpected error occurred: ", e);
        }
    }

}
